//
// Created by mio on 25-5-9.
//

#include "LoginConnection.h"

#include <mysql/mysql.h>
#include <iostream>

#include "ORMManager.h"

#define TIMEOUT 60

LoginConnection::LoginConnection(TaskScheduler* scheduler, int socket) :
    TcpConnection(scheduler, socket)
{
    this->SetReadCallback([this](std::shared_ptr<TcpConnection> conn, BufferReader& buffer)
    {
        return this->OnRead(buffer);
    });
}

LoginConnection::~LoginConnection()
{
    Clear();
}

void LoginConnection::Clear()
{

}

bool LoginConnection::OnRead(BufferReader& buffer)
{
    if (buffer.ReadableBytes() > 0)
    {
        HandleMessage(buffer);
    }
    return true;
}

void LoginConnection::HandleMessage(BufferReader& buffer)
{
    if (buffer.ReadableBytes() < sizeof(packet_head)) return;
    packet_head* head = (packet_head*)buffer.Peek();
    if (buffer.ReadableBytes() < head->len) return;
    switch (head->cmd)
    {
    case LOGIN:
        HandleLogin((packet_head*)buffer.Peek());
        break;
    case REGISTER:
        HandleRegister((packet_head*)buffer.Peek());
        break;
    case DESTORY:
        HandleDestory((packet_head*)buffer.Peek());
        break;
    default:
        break;
    }
    buffer.Retrieve(head->len);
}

bool LoginConnection::IsTimeout(uint64_t timestamp)
{
    //获取当前时间
    auto now = std::chrono::system_clock::now();
    auto nowTimestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();

    //计算差值
    int64_t time = nowTimestamp - timestamp;
    return abs(time) > TIMEOUT;
}

void LoginConnection::HandleLogin(const packet_head* data)
{
    LoginResult reply;
    UserLogin* login = (UserLogin*)data;
    if (IsTimeout(login->timestamp))
    {
        reply.result = REQUEST_TIMEOUT;
    }
    else
    {
        std::string code = login->GetCode(); //我们需要判断用户是否存在
        MYSQL_ROW row = ORMManager::GetInstance()->UserLogin(code.c_str());
        if (row == nullptr) //用户未注册
        {
            reply.result = SERVER_ERROR;
        }
        else
        {
            // 判断用户是否已经登录
            if (atoi(row[4])) // 在线
            {
                reply.result = ALREADY_LOGIN;
            }
            else
            {
                reply.result = S_OK;
                reply.SetIP("127.0.0.1");
                reply.port = 6539;
                //修改记录
                //我们先获取当前用户消息
                //获取当前时间
                auto now = std::chrono::system_clock::now();
                auto nowTimestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
                ORMManager::GetInstance()->insertClient(row[0], row[1], row[2], row[3], 1, nowTimestamp, "127.0.0.1");
            }
        }
    }
    this->Send((const char*)&reply, reply.len);
}

void LoginConnection::HandleRegister(const packet_head* data)
{
    RegisterResult reply;
    UserRegister* login = (UserRegister*)data;
    if (IsTimeout(login->timestamp))
    {
        reply.result = REQUEST_TIMEOUT;
    }
    else
    {
        std::string code = login->GetCode();
        // 通过数据库来查询code是否存在
        MYSQL_ROW row = ORMManager::GetInstance()->UserLogin(code.c_str());
        if (row == nullptr)// 未注册
        {
            ORMManager::GetInstance()->UserRegister(login->GetName().c_str(), login->GetCount().c_str(),
                login->GetPasswd().c_str(), login->GetCode().c_str(), "127.0.0.1");
            reply.result = S_OK;
        }
        else
        {
            reply.result = ALREADY_REDISTERED;
        }
        this->Send((const char*)&reply, reply.len);
    }
}

void LoginConnection::HandleDestory(const packet_head* data)
{
    UserDestory* destory = (UserDestory*)data;
    ORMManager::GetInstance()->UserDestroy(destory->GetCode().c_str());
}
